// 该文件中的代码旨在设置环境变量。
// 需要外部传参。

// 头文件引用
// 官方库
#include <string>
#include <windows.h>
#include <winreg.h>
#include <vector>
#include <sstream>

// 项目专用函数库
#include "GetEnvironmentCommon.h"





// 设置环境变量
bool AddToSystemPath(int GetInstallPosition, std::wstring InstallRelativePath) {

    // 向系统中设置环境变量
    std::wstring newPath;
    if (GetInstallPosition == 1) 
        newPath = L"D:\\Environment\\" + InstallRelativePath; // 替换为需要添加的路径
    else
        newPath = L"C:\\Environment\\" + InstallRelativePath; // 替换为需要添加的路径

    HKEY hKey;
    // 打开系统环境变量注册表键
    LONG result = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
        L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
        0, KEY_READ | KEY_WRITE, &hKey);
    if (result != ERROR_SUCCESS) {
        // std::cerr << "无法打开注册表键，错误代码：" << result << std::endl;
        return false;
    }

    DWORD type;
    DWORD size = 0;
    // 获取Path值的类型和大小
    result = RegQueryValueExW(hKey, L"Path", nullptr, &type, nullptr, &size);
    if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
        // std::cerr << "查询Path值失败，错误代码：" << result << std::endl;
        RegCloseKey(hKey);
        return false;
    }

    std::wstring currentPath;
    if (size > 0) {
        std::vector<wchar_t> buffer(size / sizeof(wchar_t) + 1);
        result = RegQueryValueExW(hKey, L"Path", nullptr, &type, reinterpret_cast<LPBYTE>(buffer.data()), &size);
        if (result != ERROR_SUCCESS) {
            // std::cerr << "读取Path值失败，错误代码：" << result << std::endl;
            RegCloseKey(hKey);
            return false;
        }
        currentPath = buffer.data();
    }

    // 分割路径检查是否存在
    std::wstringstream ss(currentPath);
    std::wstring segment;
    std::vector<std::wstring> paths;
    while (std::getline(ss, segment, L';')) {
        if (!segment.empty()) {
            paths.push_back(segment);
        }
    }

    bool exists = false;
    for (const auto& path : paths) {
        if (path == newPath) {
            exists = true;
            break;
        }
    }

    if (exists) {
        // std::wcout << L"路径已存在，无需添加。" << std::endl;
        RegCloseKey(hKey);
        return true;
    }

    // 追加新路径
    if (!currentPath.empty() && currentPath.back() != L';') {
        currentPath += L';';
    }
    currentPath += newPath;

    // 写回注册表
    result = RegSetValueExW(hKey, L"Path", 0, type,
        reinterpret_cast<const BYTE*>(currentPath.c_str()),
        (currentPath.size() + 1) * sizeof(wchar_t));
    if (result != ERROR_SUCCESS) {
        // std::cerr << "写入注册表失败，错误代码：" << result << std::endl;
        RegCloseKey(hKey);
        return false;
    }

    RegCloseKey(hKey);

    // 通知系统环境变量已更改
    DWORD sendResult = SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
        (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 5000, nullptr);
    // if (!sendResult) {
    //     std::cerr << "发送通知失败。" << std::endl;
    // }

    return true;
}


// 条理性设置环境变量 - 设置 1 个环境变量
bool OrderlinessSetEnvironmentVariables_1(int GetInstallPosition, std::wstring InstallRelativePath_1) {
    bool SetEnvironmentVariables = AddToSystemPath(GetInstallPosition, InstallRelativePath_1);

    // 如果添加路径失败
    if (!SetEnvironmentVariables)
        return false; // 标记为执行失败

    return true; // 标记为执行成功
}


// 条理性设置环境变量 - 设置 2 个环境变量
bool OrderlinessSetEnvironmentVariables_2(int GetInstallPosition, std::wstring InstallRelativePath_1, std::wstring InstallRelativePath_2) {
    bool SetEnvironmentVariables = AddToSystemPath(GetInstallPosition, InstallRelativePath_1) && AddToSystemPath(GetInstallPosition, InstallRelativePath_2);

    // 如果添加路径失败
    if (!SetEnvironmentVariables)
        return false; // 标记为执行失败

    return true; // 标记为执行成功
}